package com.imay.live.activity;

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.example.zhouwei.library.CustomPopWindow;
import com.imay.base.activity.BaseActivity;
import com.imay.base.util.StringUtil;
import com.imay.base.util.ViewUtil;
import com.imay.live.IMApplication;
import com.imay.live.activity.discovery.FollowControl;
import com.imay.live.adapter.TextMessageListAdapter;
import com.imay.live.helper.EventHelper;
import com.imay.live.logic.ChatTimeLogic;
import com.imay.live.model.NotifyMessageModel;
import com.imay.live.model.SendMessageModel;
import com.imay.live.model.TextMessageModel;
import com.imay.live.proto.ErrorResult;
import com.imay.live.proto.Result;
import com.imay.live.proto.ResultNoData;
import com.imay.live.proto.helper.ProtoCallBack;
import com.imay.live.proto.helper.ProtoHttpFactory;
import com.imay.live.proto.helper.ProtoRequest;
import com.imay.live.proto.helper.ProtoRequestHelper;
import com.imay.live.utils.AppUtil;
import com.imay.live.utils.ModelCovertUtil;
import com.imay.live.utils.PopupWindowUtil;
import com.imay.live.utils.ToastUtil;
import com.imay.live.view.refresh.RefreshView;
import com.imay.live.R;
import com.imay.tbas_api.IMYTBASObject;
import com.imay.tsnackbar.ScreenUtil;
import com.lcodecore.tkrefreshlayout.footer.LoadingView;
import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;

import java.util.ArrayList;
import java.util.List;

import static com.imay.live.proto.ResultCode.CodeSuccess;

/**
 * created by nick
 * 私信聊天界面
 */
public class ChatActivity extends BaseActivity implements View.OnClickListener, ProtoCallBack, BaseQuickAdapter.OnItemChildClickListener, BaseQuickAdapter.OnItemChildLongClickListener {

    private TwinklingRefreshLayout trl_refresh_message_chat;
    private CheckBox cb_follow_chat;
    private android.support.v7.widget.RecyclerView rv_message_chat;
    private LinearLayout ll_input_panel;
    private EditText et_content_chat;
    private Button btn_send_chat;
    private String sendMessgeCommand, loadMessageListCommand, deleteMessageCommand;
    private long targetUid;
    private String name;
    public static final String TAG_TARGETUID = "tag_targetuid";
    public static final String TAG_NAME = "tag_name";
    private int count = 20;
    private int listOffset;
    private TextMessageListAdapter textMessageListAdapter;
    private TextMessageModel textMessageModel;
    private List<TextMessageModel.RecordModel> recordModels;
    private RelativeLayout rl_chat;
    private IMYTBASObject messageReceive;
    private RelativeLayout rl_follow_chat;
    private Animator animator;
    private IMYTBASObject followChangeListener;
    private String createFollowCommand;
    private CustomPopWindow menuWindow;
    private View contentView;
    private int longClickPosition;
    private boolean isSending;

    public static void start(Context context, long targetUid, String name) {
        Intent starter = new Intent(context, ChatActivity.class);
        starter.putExtra(TAG_TARGETUID, targetUid);
        starter.putExtra(TAG_NAME, name);
        context.startActivity(starter);
    }

    public static void startActivityForResult(Activity context, long targetUid, String name, int requestCode) {
        Intent starter = new Intent(context, ChatActivity.class);
        starter.putExtra(TAG_TARGETUID, targetUid);
        starter.putExtra(TAG_NAME, name);
        context.startActivityForResult(starter, requestCode);
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_chat;
    }

    @Override
    protected void initView(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
        com.imay.live.utils.ViewUtil.setForgroundRadius($(R.id.rl_chat));

        recordModels = new ArrayList<>();
        initArguments();
        setTitle(name);
        bindViews();
        addListener();
        loadMessageList();
        addMessageReceiveListener();
        registerSocketNotify();
    }

    private void initArguments() {
        targetUid = getIntent().getLongExtra(TAG_TARGETUID, 0);
        name = getIntent().getStringExtra(TAG_NAME);
        IMApplication.getInstance().setCurrentChatUid(targetUid);
    }

    private void bindViews() {
        trl_refresh_message_chat = $(R.id.trl_refresh_message_chat);
        rl_chat = $(R.id.rl_chat);
        cb_follow_chat = $(R.id.cb_follow_chat);
        rv_message_chat = $(R.id.rv_message_chat);
        ll_input_panel = $(R.id.ll_input_panel);
        et_content_chat = $(R.id.et_content_chat);
        btn_send_chat = $(R.id.btn_send_chat);
        rl_follow_chat = $(R.id.rl_follow_chat);
        rv_message_chat.setLayoutManager(new LinearLayoutManager(this));

        trl_refresh_message_chat.setHeaderView(new RefreshView(this));
        trl_refresh_message_chat.setEnableLoadmore(false);
        trl_refresh_message_chat.setEnableOverScroll(false);
        trl_refresh_message_chat.setOnRefreshListener(new RefreshListenerAdapter() {
            @Override
            public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
                listOffset = recordModels.size();
                loadMessageList();
            }

        });
    }

    private void addListener() {
        btn_send_chat.setOnClickListener(this);
        cb_follow_chat.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send_chat:
                if (TextUtils.isEmpty(et_content_chat.getText()) || "".equals(et_content_chat.getText().toString().trim())) {
                    return;
                }
                if (!isSending) {
                    isSending = true;
                    sendMessage();
                }
                break;
            case R.id.cb_follow_chat:
                createFollow();
                break;
            case R.id.tv_delete_chat:
                menuWindow.dissmiss();
                deleteMessage();
                break;
            case R.id.tv_copy_chat:
                menuWindow.dissmiss();
                AppUtil.copy(this, recordModels.get(longClickPosition).getContent());
                break;
        }

    }

    private void sendMessage() {
        sendMessgeCommand = ProtoRequestHelper.task(ProtoHttpFactory.sendMessage(targetUid, et_content_chat.getText().toString())).setTag(this.hashCode()).request(this);
    }

    private void loadMessageList() {
        loadMessageListCommand = ProtoRequestHelper.task(ProtoHttpFactory.getMessageList(targetUid, listOffset, count)).setTag(this.hashCode()).request(this);
    }

    private void createFollow() {
        createFollowCommand = ProtoRequestHelper.task(ProtoHttpFactory.createFollow(targetUid)).setTag(this.hashCode()).request(this);
    }

    @Override
    public void onRequestSuccess(String command, String data) {
        Log.e("ChatActivity", data);
        refreshFinish();
        if (command.equals(sendMessgeCommand)) {
            isSending = false;
            Result<SendMessageModel> messageModelResult = JSON.parseObject(data, new TypeReference<Result<SendMessageModel>>() {
            }.getType());
            if (messageModelResult.result == CodeSuccess) {
                refreshViewAfterSend(messageModelResult.data);
            } else {
                ErrorResult.toastError(this, messageModelResult.result);
            }
        } else if (command.equals(loadMessageListCommand)) {
            Result<TextMessageModel> textMessageModelResult = JSON.parseObject(data, new TypeReference<Result<TextMessageModel>>() {
            }.getType());
            if (textMessageModelResult.result == CodeSuccess) {
                if (listOffset == 0) {
                    recordModels.clear();
                }
                textMessageModel = textMessageModelResult.data;

                recordModels.addAll(0, textMessageModelResult.data.getRecords());
                bindAdapter();
                if (recordModels.size() > count) {
                    rv_message_chat.scrollToPosition(textMessageModelResult.data.getRecords().size());
                } else {
                    rv_message_chat.scrollToPosition(recordModels.size() - 1);
                }
            } else {
                ErrorResult.toastError(this, textMessageModelResult.result);
            }
        } else if (command.equals(createFollowCommand)) {
            Result result = JSON.parseObject(data, new TypeReference<Result>() {
            }.getType());
            if (result.result == CodeSuccess) {
                EventHelper.postFollowChange(targetUid, true);
            } else {
                ErrorResult.toastError(this, result.result);
            }
        } else if (command.equals(deleteMessageCommand)) {
            ResultNoData resultNoData = JSON.parseObject(data, ResultNoData.class);
            if (resultNoData.result == CodeSuccess) {
                recordModels.remove(longClickPosition);
                bindAdapter();
//                EventHelper.postMessageSend(JSON.toJSONString(getSendMessageModel()));
            } else {
                ToastUtil.show(this, R.string.delete_record_fail);
            }
        }

    }

    @Override
    public void onRequestError(String command, int code, String message) {
        isSending = false;
        ErrorResult.toastError(this, code);
        refreshFinish();

    }

    private void bindAdapter() {
        settleTime(recordModels);
        if (textMessageListAdapter == null) {
            textMessageListAdapter = new TextMessageListAdapter(recordModels, textMessageModel.getYourHeadImg(), textMessageModel.getMyHeadImg());
            View view = new View(this);
            textMessageListAdapter.addHeaderView(view);
            rv_message_chat.setAdapter(textMessageListAdapter);
            rv_message_chat.addItemDecoration(new HorizontalDividerItemDecoration.Builder(this)
                    .sizeResId(R.dimen.size_15dp)
                    .color(Color.TRANSPARENT)
                    .showLastDivider()
                    .build());
            textMessageListAdapter.setOnItemChildClickListener(this);
            textMessageListAdapter.setOnItemChildLongClickListener(this);
        } else {
            textMessageListAdapter.setNewData(recordModels);

        }
    }

    private void refreshFinish() {
        if (trl_refresh_message_chat != null) {
            trl_refresh_message_chat.finishRefreshing();
        }
    }


    private void moveToBottom() {
        rv_message_chat.scrollToPosition(recordModels.size() - 1);
    }

    private void addMessageReceiveListener() {
        messageReceive = new IMYTBASObject(false);
        messageReceive.stringCommand = EventHelper.EVENT_MESSAGE_NOTIFY;
        messageReceive.setDataResultListener(new IMYTBASObject.OnDataResultListener() {
            @Override
            public void onCommandTaskSuccess(IMYTBASObject imytbasObject) {
                NotifyMessageModel notifyMessageModel = JSON.parseObject(imytbasObject.stringData, new TypeReference<NotifyMessageModel>() {
                }.getType());
                refreshViewAfterMessageNotify(notifyMessageModel);
            }
        });
        messageReceive.addEventListenWithTBASObject();
    }

    private void refreshViewAfterMessageNotify(NotifyMessageModel notifyMessageModel) {
        if (recordModels == null) {
            return;
        }
        recordModels.add(ModelCovertUtil.convertNotifyMessageModelToRecordModel(notifyMessageModel));

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                bindAdapter();
                moveToBottom();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (messageReceive != null) {
            messageReceive.destroy();
        }
        if (followChangeListener != null) {
            followChangeListener.destroy();
        }
    }

    private void refreshViewAfterSend(SendMessageModel model) {
        if (model.isAllFollow()) {
            model.setContentLocal(et_content_chat.getText().toString());
            EventHelper.postMessageSend(JSON.toJSONString(model));
            recordModels.add(ModelCovertUtil.convertMessageRecordModel(model, et_content_chat.getText().toString()));
            bindAdapter();
            et_content_chat.setText("");
            rv_message_chat.scrollToPosition(recordModels.size() - 1);
        } else if (model.isMyNotFollow()) {
            rl_follow_chat.setVisibility(View.VISIBLE);
            startAnim();
        } else if (model.isNotFollowMe()) {
            TextMessageModel.RecordModel recordModel = new TextMessageModel.RecordModel();
            recordModel.setUid(-1);
            recordModel.setContent(getString(R.string.chat_not_follow));
            recordModels.add(recordModel);
            bindAdapter();
            et_content_chat.setText("");
            rv_message_chat.scrollToPosition(recordModels.size() - 1);
        }
    }

    private void startAnim() {
        if (animator == null) {
            animator = AnimatorInflater.loadAnimator(this, R.animator.chat_follow_btn_anim);
            animator.setTarget(cb_follow_chat);
        }
        animator.start();
    }

    protected void registerSocketNotify() {
        followChangeListener = new IMYTBASObject(false);
        followChangeListener.stringCommand = EventHelper.EVENT_FOLLOW_UICHANGE;
        followChangeListener.setDataResultListener(new IMYTBASObject.OnDataResultListener() {
            @Override
            public void onCommandTaskSuccess(final IMYTBASObject object) {
                refreshFollowStatus(object.stringData);
            }
        });
        followChangeListener.addEventListenWithTBASObject();

    }

    private void refreshFollowStatus(String uidStr) {
        boolean isFollow = true;
        int sp = uidStr.indexOf("#");
        if (sp > 0) {
            uidStr = uidStr.substring(0, sp);
            isFollow = false;
        }
        final int uid = Integer.parseInt(uidStr);
        final boolean finalIsFollow = isFollow;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (uid == targetUid) {
                    cb_follow_chat.setChecked(finalIsFollow);
                    rl_follow_chat.setVisibility(finalIsFollow ? View.GONE : View.VISIBLE);
                }
            }
        });

    }

    /**
     * 对时间做处理
     *
     * @param recordModels
     */
    private void settleTime(List<TextMessageModel.RecordModel> recordModels) {
        if (recordModels == null || recordModels.size() == 0) {
            return;
        }
        int currentTime = 0;
        for (int i = 0; i < recordModels.size(); i++) {
            if (recordModels.get(i).getChatRecordId() == 0) {
                continue;
            }
            if (i == 0 || !ChatTimeLogic.isBettewTowMinute(currentTime, recordModels.get(i).getCreateAt())) {
                recordModels.get(i).setShowTime(ChatTimeLogic.getMessageTime(recordModels.get(i).getCreateAt()));
            }
            currentTime = recordModels.get(i).getCreateAt();
        }
    }

    @Override
    public void onBackPressed() {
        IMApplication.getInstance().setCurrentChatUid(0);
        if (!TextUtils.isEmpty(sendMessgeCommand) || !TextUtils.isEmpty(deleteMessageCommand)) {
            setResult(RESULT_OK);
        }
        super.onBackPressed();
    }

    @Override
    public void comeBack() {
        IMApplication.getInstance().setCurrentChatUid(0);
        if (!TextUtils.isEmpty(sendMessgeCommand) || !TextUtils.isEmpty(deleteMessageCommand)) {
            setResult(RESULT_OK);
        }
        super.comeBack();
    }

    @Override
    protected boolean isTranslucentStatus() {
        return false;
    }

    @Override
    public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
        ProfileActivity.start(this, recordModels.get(position).getUid());

    }

    @Override
    public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
        longClickPosition = position;
        showMenu(view, R.id.tv_content_chat_text_left == view.getId());
        return false;
    }

    private void showMenu(View anchorView, boolean isLeft) {
        if (menuWindow == null) {
            initMenuWindow();
        }
        // 设置好参数之后再show
        int titleBarHeight = getTitleBar().getHeight();
        int windowPos[] = PopupWindowUtil.calculatePopWindowPos(anchorView, contentView, titleBarHeight);
        if (isLeft) {
            windowPos[0] = anchorView.getLeft();
        } else {
            int right = anchorView.getRight() - contentView.getMeasuredWidth();
            windowPos[0] = right;
        }
        menuWindow.showAtLocation(anchorView, Gravity.TOP | Gravity.START, windowPos[0], windowPos[1]);
    }

    private void initMenuWindow() {
        contentView = LayoutInflater.from(this).inflate(R.layout.menu_chat_record, null);
        contentView.findViewById(R.id.tv_copy_chat).setOnClickListener(this);
        contentView.findViewById(R.id.tv_delete_chat).setOnClickListener(this);
        menuWindow = new CustomPopWindow.PopupWindowBuilder(this)
                .setView(contentView)
                .size(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)//显示大小
                .create();
    }

    private void deleteMessage() {
        long messageid = recordModels.get(longClickPosition).getChatRecordId();
        deleteMessageCommand = ProtoRequestHelper.task(ProtoHttpFactory.deleteRecord(messageid)).setTag(this.hashCode()).request(this);
    }

    private SendMessageModel getSendMessageModel() {
        if (recordModels.size() == 0) {
            return new SendMessageModel();
        } else {
            return ModelCovertUtil.convertSendMessageModel(recordModels.get(recordModels.size() - 1));
        }
    }
}
